package rss;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import org.apache.commons.lang3.StringEscapeUtils;

import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

public class Article {
	private String title;
	private String description;
	private URL link;
	private String id;
	private Date date;

	public static Vector<Article> parseArticles(String url) throws MalformedURLException {
		return parseArticles(new URL(url));
	}
	
	public static Vector<Article> parseArticles(Vector<URL> urls) {
		return parseArticles(urls, null);
	}
	
	public static Vector<Article> parseArticles(Vector<URL> urls, ArticleLoadedListener listener) {
		Vector<Article> articles = new Vector<Article>();
		
		for(URL url: urls) {
			articles.addAll(parseArticles(url, listener));
		}
		
		return articles;
	}
	
	public static Vector<Article> parseArticles(URL url) {
		return parseArticles(url, null);
	}
	
	public static Vector<Article> parseArticles(URL url, ArticleLoadedListener listener) {
		Vector<Article> articles = new Vector<Article>();
		SyndFeedInput sfi = new SyndFeedInput();
		Exception ex = null;
		
		SyndFeed feed = null;
		
		try {
			feed = sfi.build(new XmlReader(url));
		} catch (IllegalArgumentException e) {
			ex = e;
		} catch (FeedException e) {
			ex = e;
		} catch (IOException e) {
			ex = e;
		}
		
		if (listener != null && ex != null) {
			listener.notify(ex);
		}
		else {
			List<SyndEntry> entries = feed.getEntries();
	
			for (SyndEntry entry : entries) {
				Article article = new Article();
				article.setTitle(entry.getTitle());
				
				String description = entry.getDescription().getValue();
				
				if (description == null || description.equals("")) {
					StringBuffer sb = new StringBuffer();
					
					for (Object content: entry.getContents()) {
						sb.append(((SyndContent)content).getValue());
					}
					
					description = sb.toString().trim();
				}
				
				article.setDescription(description);
				article.setId(entry.getLink());
				
				try {
					article.setLink(new URL(entry.getLink()));
				} catch (MalformedURLException e) {
					if (listener != null) {
						listener.notify(e);
					}
				}
				
				if (article.getLink() != null) {
					Date date = entry.getPublishedDate();
					
					if (date == null) {
						date = entry.getUpdatedDate();
					}
					
					article.setDate(date);
					
					if (listener != null) {
						listener.notify(article);
					}
					
					articles.add(article);
				}
			}
		}

		return articles;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getPlainDescription() {
		return StringEscapeUtils.unescapeXml(description.replaceAll("<(.+?)>", "").replaceAll("\\s+", " "));
	}
	
	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public URL getLink() {
		return link;
	}

	public void setLink(URL link) {
		this.link = link;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
	
	public String toString() {
		StringBuffer sb = new StringBuffer();
		
		sb.append("title:" +  title + "\n");
		sb.append("link:" + link.toString() + "\n");
		
		if (date != null) {
			sb.append("date:" + date.toString() + "\n");
		}
		
		sb.append("id:" + id + "\n");
		sb.append("description:" + description + "\n");
		
		return sb.toString();
	}

}
